#include "user_main.h"

#include "nvs_flash.h"
#include "nvs.h"

static const char *TAG = "demo";
    
int shortdown(void)
{
    ESP_LOGW(TAG, "===== SHOART DOWN =====");
    return 0;
}
    
int longdown(void)
{
    ESP_LOGW(TAG, "===== LONG DOWN =====");
    return 0;
}

void system_monitor(void *argv)
{
    Gpio_Init();
    set_key_shortDown_callback(200, shortdown);
    set_key_longDown_callback(2000, longdown);

    while (1)
    {
        KEY_scanf();
        LED_control();
        vTaskDelay(100/portTICK_RATE_MS);
    }
}

void Networl_init(void)
{
    system_status_t *sys_sta = get_sys_sta();
    my_wifi_t wifi_info = {
        .ssid = "ESP8266",
        .password = "00000000",
        .max_connection = 1,
    };

    ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");
    wifi_init_softap(&wifi_info);
}

void HeapStack_monitor(void *argv)
{
    task_handle_managa_t *task_handle_cur = NULL;
    task_handle_managa_t *task_handle_haed = get_task_handle_haed();
    while (1)
    {
        printf("\n");
        ESP_LOGI(TAG, "free_heap_size: %d KB", esp_get_free_heap_size() / 1024);
        ESP_LOGI(TAG, "minimum_free_heap_size: %d KB", esp_get_minimum_free_heap_size() / 1024);

        for (task_handle_cur = task_handle_haed; task_handle_cur != NULL; 
                task_handle_cur = task_handle_cur->next)
        {
            if (task_handle_cur->handle != NULL) {
                ESP_LOGI(TAG, "%s stack:%d B", task_handle_cur->name, uxTaskGetStackHighWaterMark(task_handle_cur->handle) * 4);
            }
        }
        printf("\n");
        vTaskDelay(1000/portTICK_PERIOD_MS);
    }
}

void user_nvs_init(void)
{
    esp_err_t err = nvs_flash_init();
    if (err == ESP_ERR_NVS_NO_FREE_PAGES) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        err = nvs_flash_init();
    }
    ESP_ERROR_CHECK( err );

    nvs_handle my_handle;
    err = nvs_open("storage", NVS_READWRITE, &my_handle);
    if (err != ESP_OK) {
        printf("Error (%s) opening NVS handle!\n", esp_err_to_name(err));
    } 
    int32_t restart_counter = 0;
    err = nvs_get_i32(my_handle, "restart_counter", &restart_counter);
    switch (err) {
        case ESP_OK:
            printf("Restart counter = %d\n", restart_counter);
            break;
        case ESP_ERR_NVS_NOT_FOUND:
            printf("The value is not initialized yet!\n");
            break;
        default :
            printf("Error (%s) reading!\n", esp_err_to_name(err));
    }

    restart_counter++;
    err = nvs_set_i32(my_handle, "restart_counter", restart_counter);
    if (err != ESP_OK)
            printf("Error (%s) seting!\n", esp_err_to_name(err));
    err = nvs_commit(my_handle);
    if (err != ESP_OK)
            printf("Error (%s) seting!\n", esp_err_to_name(err));
    nvs_close(my_handle);
}


void app_main()
{   
    system_status_t *sys_sta = get_sys_sta();
    const esp_app_desc_t *app_desc = esp_ota_get_app_description();
    sys_sta->version = (char *)app_desc->version;
    ESP_LOGI(TAG, "app_version:%s", sys_sta->version); 

    user_nvs_init();

    printf("free_heap_size: %d KB\n", esp_get_free_heap_size() / 1024);
    printf("minimum_free_heap_size: %d KB\n", esp_get_minimum_free_heap_size() / 1024);

    new_task(HeapStack_monitor, "HeapStack_monitor", 1024, NULL, 21);
    new_task(system_monitor, "system_monitor", 1024, NULL, 23);
    
    ESP_LOGI(TAG, "init ap mode");

    Networl_init();

    ESP_LOGI(TAG, "Run");
}
